package com.sen.common.struts;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

import com.sen.common.jquery.TinyGridParam;
import com.sen.common.jquery.TinyGridUtils;
import com.sen.common.orm.PageContext;
import com.sen.common.utils.Joiner;
import com.sen.common.utils.JsonBinder;
import com.sen.common.utils.web.Struts2Utils;

/**
 * struts2所有用户定义action的基类.
 * 
 * @author sen
 */
public abstract class BaseAction extends ActionSupport implements ServletRequestAware,
		ServletResponseAware, SessionAware {

	/**
	 * 组合字符串的缺省分隔符:-_-
	 */
	public static final String IANSWER_SEPARATOR = "-_-";

	private static final int FIRST_PAGE = 1;

	private static final long serialVersionUID = 230840749427604033L;

	private static final String DATE_PATTERN = "yyyy-MM-dd";
	private static final String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm";
	
	private static JsonBinder jsonBinder = JsonBinder.buildNormalBinder();
	static {
		jsonBinder.setDateFormat(DATE_TIME_PATTERN);
	}
	
	protected ActionContext actionContext;
	protected Map<String, Object> session;
	protected HttpServletRequest request;
	protected HttpServletResponse response;

	private TinyGridParam gridParam;
	private int resultsPerPage;
	
	public BaseAction() {
		PageContext.clean();
		actionContext = ActionContext.getContext();
	}

	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	public void setServletResponse(HttpServletResponse response) {
		this.response = response;
	}

	public void setServletRequest(HttpServletRequest request) {
		this.request = request;
	}

	/**
	 * 获取被查询记录的总数.
	 */
	protected int getTotal() {
		int recordCount = PageContext.getTotalElements().intValue();
		PageContext.clean();
		return recordCount;
	}

	/**
	 * 获取当前分页的页码.
	 */
	protected int getPage() {
		lazyInitGridParam();
		return gridParam.getPage();
	}

	protected int getSkip() {
		lazyInitGridParam();
		return gridParam.getSkip();
	}

	protected int getMax() {
		lazyInitGridParam();
		return gridParam.getMax();
	}

	protected String getOrderSql() {
		lazyInitGridParam();
		return gridParam.getOrderSql();
	}

	protected String getSortName() {
		lazyInitGridParam();
		return gridParam.getSortName();
	}

	protected String getSortOrder() {
		lazyInitGridParam();
		return gridParam.getSortOrder();
	}

	protected int getResultsPerPage() {
		if (resultsPerPage > 0) {
			return resultsPerPage;
		}
		return gridParam.getResultsPerPage();
		
	}

	protected void setResultsPerPage(int resultsPerPage) {
		lazyInitGridParam();
		gridParam.setResultsPerPage(resultsPerPage);
		this.resultsPerPage = resultsPerPage;
	}

	private String[] getBeanProperties() {
		lazyInitGridParam();
		return gridParam.getBeanProperties();
	}

	private void lazyInitGridParam() {
		if (!existsGridParam()) {
			gridParam = new TinyGridParam(request);
		}
	}

	protected boolean existsGridParam() {
		return null != gridParam;
	}

	/**
	 * 带分页, 时间精确到自定义精度，默认是分钟
	 */
	protected <T> void writeJsonUsingPager(List<T> beans, String dateFormat) {
		if (StringUtils.isBlank(dateFormat)) {
			writeJsonUsingPager(beans);
			return;
		}
		writeJson(TinyGridUtils.toJson(beans, getBeanProperties(), getPage(),
				getTotal(), dateFormat));
	}

	/**
	 * 带分页, 时间精确到分钟
	 */
	protected <T> void writeJsonUsingPager(List<T> beans) {
		writeJson(TinyGridUtils.toJson(beans, getBeanProperties(), getPage(),
				getTotal(), BaseAction.DATE_TIME_PATTERN));
	}

	/**
	 * 带分页, 时间精确到天
	 */
	protected <T> void writeJsonWithDateUsingPager(List<T> beans) {
		writeJson(TinyGridUtils.toJson(beans, getBeanProperties(), getPage(),
				getTotal(), BaseAction.DATE_PATTERN));
	}

	/**
	 * 不带分页, 时间精确到自定义精度，默认是分钟
	 */
	protected <T> void writeJsonNoPager(List<T> beans, String dateFormat) {
		if (StringUtils.isBlank(dateFormat)) {
			writeJsonNoPager(beans);
			return;
		}
		writeJson(TinyGridUtils.toJson(beans, getBeanProperties(),
				BaseAction.FIRST_PAGE, getCollectionSize(beans), dateFormat));
	}

	/**
	 * 不带分页, 时间精确到分钟
	 */
	protected <T> void writeJsonNoPager(List<T> beans) {
		writeJson(TinyGridUtils.toJson(beans, getBeanProperties(),
				BaseAction.FIRST_PAGE, getCollectionSize(beans),
				BaseAction.DATE_TIME_PATTERN));
	}

	private <T> int getCollectionSize(List<T> beans) {
		return null == beans ? 0 : beans.size();
	}

	/**
	 * 不带分页, 时间精确到天
	 */
	protected <T> void writeJsonWithDateNoPager(List<T> beans) {
		writeJson(TinyGridUtils.toJson(beans, getBeanProperties(),
				BaseAction.FIRST_PAGE, getCollectionSize(beans),
				BaseAction.DATE_PATTERN));
	}

	/**
	 * 输出字符串, 分隔符为:<code>IANSWER_SEPARATOR</code>
	 */
	protected void writePlainText(boolean isSuccessful, String... values) {
		writePlainText(BaseAction.IANSWER_SEPARATOR, isSuccessful, values);
	}

	protected void writePlainText(String separator, boolean isSuccessful,
			String... values) {
		writePlainText(Joiner.with(separator).join(isSuccessful, values));
	}

	protected void alertAndReturn(String msg, boolean isSuccessful) {
		StringBuffer js = new StringBuffer();
		js.append("<script type='text/javascript'>");
		js.append("window.alert('").append(msg).append("');");
		js.append("window.returnValue='").append(isSuccessful).append("';");
		js.append("window.close();");
		js.append("</script>");
		Struts2Utils.renderHtml(js.toString());
	}

	/**
	 * 输出一个json格式的字符流到前台. <br />
	 * 
	 * <b>若传给tinygrid的json信息, 请使用{@link #writeJsonNoPager(List)}或
	 * {@link #writeJsonUsingPager(List)}这两类的方法!</b>
	 * 
	 * @param beans
	 *            列表.
	 */
	protected <T> void writeJson(List<T> beans) {
		writeJson(jsonBinder.toJson(beans));
	}

	/**
	 * 输出一个json格式的字符流到前台. <br />
	 * 
	 * <b>若传给tinygrid的json信息, 请使用{@link #writeJsonNoPager(List)}或
	 * {@link #writeJsonUsingPager(List)}这两类的方法!</b>
	 * 
	 * @param obj
	 *            对象.
	 */
	protected void writeJson(Object obj) {
		writeJson(jsonBinder.toJson(obj));
	}

	/**
	 * 输出一个json格式的字符流到前台. <br />
	 * 
	 * <b>若传给tinygrid的json信息, 请使用{@link #writeJsonNoPager(List)}或
	 * {@link #writeJsonUsingPager(List)}这两类的方法!</b>
	 * 
	 * @param json
	 *            json格式的字符串.
	 */
	protected void writeJson(String json) {
		Struts2Utils.renderJson(json);
	}

	protected void writePlainText(String text) {
		Struts2Utils.renderText(text);
	}

	/**
	 * 按分隔符<code>IANSWER_SEPARATOR</code>分离字符串, 若为空串返回null.
	 */
	protected String[] split(String value) {
		if (StringUtils.isBlank(value)) {
			return ArrayUtils.EMPTY_STRING_ARRAY;
		}
		return value.split(BaseAction.IANSWER_SEPARATOR);
	}
	
	protected String appendParameter(String url, String name, String value) {
		if (url == null) {
			return StringUtils.EMPTY;
		}
		return appendParameter(new StringBuffer(url), name, value).toString();
	}
	
	protected StringBuffer appendParameter(StringBuffer url, String name, String value) {
		if (url == null) {
			return new StringBuffer(0);
		}
		if (StringUtils.contains(url.toString(), '?')) {
			url.append('&');
		} else {
			url.append('?');
		}
		url.append(name).append('=').append(value);
		return url;
	}
}
